package com.jtny.nytb.equipment.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.BeanUtils;

import com.jtny.nytb.equipment.dao.equipment.EquipmentGatewayRelationDAO;
import com.jtny.nytb.equipment.dao.equipment.EquipmentInfoDAO;
import com.jtny.nytb.equipment.dao.equipment.EquipmentLabelDAO;
import com.jtny.nytb.equipment.dao.equipment.EquipmentParamDAO;
import com.jtny.nytb.equipment.dao.instrument.InstrumentDAO;
import com.jtny.nytb.equipment.dao.model.ModelDAO;
import com.jtny.nytb.equipment.dao.model.ModelParamDAO;

import com.jtny.nytb.equipment.domain.equipment.EquipmentGatewayRelationDO;
import com.jtny.nytb.equipment.domain.equipment.EquipmentInfoDO;
import com.jtny.nytb.equipment.domain.equipment.EquipmentLabelDO;
import com.jtny.nytb.equipment.domain.equipment.EquipmentParamDO;
import com.jtny.nytb.equipment.domain.instrument.InstrumentDO;
import com.jtny.nytb.equipment.domain.model.ModelDO;
import com.jtny.nytb.equipment.domain.model.ModelParamDO;
import com.jtny.nytb.equipment.dto.ModelDTO;
import com.jtny.nytb.equipment.dto.device.EquipmentInfoDTO;
import com.jtny.nytb.equipment.dto.excel.ExcelEquipmentDTO;
import com.jtny.nytb.equipment.dto.excel.ExcelEquipmentLabelDTO;
import com.jtny.nytb.equipment.dto.excel.ExcelInstrumentDTO;
import com.jtny.nytb.equipment.dto.excel.ExcelParamDTO;
import com.jtny.nytb.equipment.dto.model.ExcelModelDTO;
import com.jtny.nytb.equipment.enums.CodeRuleTypeEnum;
import com.jtny.nytb.equipment.service.CodeRuleService;
import com.jtny.nytb.equipment.service.ExcelService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 智慧能源中心 - 伍天宇
 * @package com.jtny.energymonitor.equipment.service.impl
 * @fileName ExcelServiceImpl.java
 * @createTime 2023年11月23日 13:54
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */
@Service
@AllArgsConstructor
public class ExcelServiceImpl implements ExcelService {
    @Qualifier("codeRuleServiceImpl")
    private CodeRuleService codeRuleService;
    private EquipmentInfoDAO equipmentInfoDAO;
    private EquipmentParamDAO equipmentParamDAO;
    private EquipmentLabelDAO equipmentLabelDAO;
    private ModelDAO modelDAO;
    private ModelParamDAO modelParamDAO;
    private InstrumentDAO instrumentDAO;
    private EquipmentGatewayRelationDAO equipmentGatewayRelationDAO;


    /**
     * 导入 Excel 模型
     *
     * @param excelModelList Excel 模型列表
     * @return {@link Map}<{@link String}, {@link ModelDTO}>
     * @throws ServiceException 服务异常
     */
    @Override
    public Map<String, ModelDTO> importExcelModel(List<ExcelModelDTO> excelModelList)
            throws ServiceException {
        Map<String, ModelDTO> result = new HashMap<>();
        if (CollUtil.isEmpty(excelModelList)) {
            return result;
        }
        excelModelList.forEach(item -> {
            ModelDO modelDO = BeanUtils.copyToObject(item, ModelDO.class);
            modelDO.setIsMeasuringPointDeviceModel(item.getIsMeasuringPointDevice());
            modelDAO.insert(modelDO);
            Long modelId = modelDO.getId();
            List<ModelParamDO> modelParamDOS = buildModelParamDO(modelId, item.getParamList());
            if (CollUtil.isNotEmpty(modelParamDOS)) {
                modelParamDAO.insertBatch(modelParamDOS);
            }
            // 保存设备模型
            result.put(item.getName(), BeanUtils.copyToObject(modelDO, ModelDTO.class));
        });
        return result;
    }

    /**
     * Excel导入设备
     *
     * @param equipmentExcelList 设备List
     * @return {@link Map}<{@link String}, {@link EquipmentInfoDTO}>
     * @throws ServiceException 服务异常
     */
    @Override
    public Map<String, EquipmentInfoDTO> importExcelEquipment(List<ExcelEquipmentDTO> equipmentExcelList)
            throws ServiceException {
        Map<String, EquipmentInfoDTO> result = new HashMap<>();
        if (CollUtil.isEmpty(equipmentExcelList)) {
            return result;
        }
        equipmentExcelList.forEach(item -> {
            EquipmentInfoDO equipmentInfoDO = buildEquipmentDO(item);
            equipmentInfoDO.setStatus(GenericStatusEnum.DISABLE.getValue());
            // 保存设备
            equipmentInfoDAO.insert(equipmentInfoDO);
            Long equipmentId = equipmentInfoDO.getId();
            // 保存设备参数
            List<EquipmentParamDO> equipmentParamDOS = buildEquipmentParamDO(equipmentId, item.getParamList());
            if (CollUtil.isNotEmpty(equipmentParamDOS)) {
                equipmentParamDAO.insertBatch(equipmentParamDOS);
            }
            // 保存设备标签
            List<EquipmentLabelDO> equipmentLabelDOS = buildEquipmentLabelDO(equipmentId, item.getLabelList());
            if (CollUtil.isNotEmpty(equipmentLabelDOS)) {
                equipmentLabelDAO.insertBatch(equipmentLabelDOS);
            }
            EquipmentGatewayRelationDO equipmentGatewayRelationDO = buildEquipmentGatewayRelationDO(item);
            equipmentGatewayRelationDAO.insert(equipmentGatewayRelationDO);
            // 保存设备信息
            result.put(equipmentInfoDO.getName(), BeanUtils.copyToObject(equipmentInfoDO, EquipmentInfoDTO.class));
        });
        return result;
    }

    /**
     * Excel导入测量器具
     *
     * @param toSaveBatch 测量器具List
     * @return {@link Map}<{@link String}, {@link ExcelInstrumentDTO}> key:测量器具名称 value:测量器具信息
     * @throws ServiceException 服务异常
     */
    @Override
    public Map<String, ExcelInstrumentDTO> importExcelInstrument(List<ExcelInstrumentDTO> toSaveBatch) throws ServiceException {
        Map<String, ExcelInstrumentDTO> result = new HashMap<>();
        if (CollUtil.isEmpty(toSaveBatch)) {
            return result;
        }
        List<InstrumentDO> list = BeanUtils.copyToList(toSaveBatch, InstrumentDO.class);
        list.forEach(item -> {
            instrumentDAO.insert(item);
            result.put(item.getInstrumentName(), BeanUtils.copyToObject(item, ExcelInstrumentDTO.class));
        });
        return result;
    }

    /**
     * 建造网关设备关联关系
     *
     * @param dto DTO
     * @return {@link EquipmentInfoDO}
     */
    private EquipmentGatewayRelationDO buildEquipmentGatewayRelationDO(ExcelEquipmentDTO dto) {
        EquipmentGatewayRelationDO equipmentGatewayRelationDO = new EquipmentGatewayRelationDO();
        equipmentGatewayRelationDO.setGwId(dto.getGatewayIdentifier());
        equipmentGatewayRelationDO.setMcbId(dto.getDockIdentifier());
        equipmentGatewayRelationDO.setModel(dto.getName());
        return equipmentGatewayRelationDO;
    }

    /**
     * 建造设备
     *
     * @param dto DTO
     * @return {@link EquipmentInfoDO}
     */
    private EquipmentInfoDO buildEquipmentDO(ExcelEquipmentDTO dto) {
        EquipmentInfoDO equipmentInfoDO = BeanUtils.copyToObject(dto, EquipmentInfoDO.class);
        // 设置code
        String type = equipmentInfoDO.getIsMeasuringPointDevice() ? CodeRuleTypeEnum.METER.getType() : CodeRuleTypeEnum.GENERAL.getType();
        List<String> list = Arrays.asList(equipmentInfoDO.getEquipmentCodeRule().split(StrUtil.COMMA));
        List<String> idList = list.stream().filter(s -> StrUtil.isNotEmpty(s)&& !StrUtil.equals(s,"null")).collect(Collectors.toList());
        String code = codeRuleService.getCodeByCodeRuleId(type, idList);
        equipmentInfoDO.setCode(code);
        return equipmentInfoDO;
    }

    /**
     * 构建设备参数
     *
     * @param equipmentId 设备 ID
     * @param paramList   参数列表
     * @return {@link List}<{@link EquipmentParamDO}>
     */
    private List<EquipmentParamDO> buildEquipmentParamDO(Long equipmentId, List<ExcelParamDTO> paramList) {
        if (CollUtil.isEmpty(paramList)) {
            return null;
        }
        return paramList.stream().map(param -> {
            EquipmentParamDO equipmentParamDO = BeanUtils.copyToObject(param, EquipmentParamDO.class);
            equipmentParamDO.setEquipmentId(equipmentId);
            equipmentParamDO.setStatus(GenericStatusEnum.NORMAL.getValue());
            return equipmentParamDO;
        }).collect(Collectors.toList());
    }

    /**
     * 构建设备标签 DO
     *
     * @param equipmentId 设备 ID
     * @param paramList   参数列表
     * @return {@link List}<{@link EquipmentLabelDO}>
     */
    private List<EquipmentLabelDO> buildEquipmentLabelDO(Long equipmentId, List<ExcelEquipmentLabelDTO> paramList) {
        if (CollUtil.isEmpty(paramList)) {
            return null;
        }
        return paramList.stream().map(param -> {
            EquipmentLabelDO equipmentLabelDO = BeanUtils.copyToObject(param, EquipmentLabelDO.class);
            equipmentLabelDO.setEquipmentId(equipmentId);
            return equipmentLabelDO;
        }).collect(Collectors.toList());
    }

    /**
     * 构建模型参数
     *
     * @param modelId   模型ID
     * @param paramList 参数列表
     * @return {@link List}<{@link ModelParamDO}>
     */
    private List<ModelParamDO> buildModelParamDO(Long modelId, List<ExcelParamDTO> paramList) {
        if (CollUtil.isEmpty(paramList)) {
            return null;
        }
        return paramList.stream().map(param -> {
            ModelParamDO modelParamDO = BeanUtils.copyToObject(param, ModelParamDO.class);
            modelParamDO.setModelId(modelId);
            modelParamDO.setStatus(0);
            return modelParamDO;
        }).collect(Collectors.toList());
    }

}
